Матч
184, Построение команд (TeamBuilder)
Дивизион 2, Уровень
3
Рассмотрим некоторую странную
игру, в которой поле состоит из определенных мест, в которых могут находиться
игроки. Известно, из каких мест и в какие можно передвигаться игрокам. При этом
известно, что если из i существует
путь в j, то не всегда из j можно попасть в i. Необходимо определить количество мест, из которых существуют
пути во все остальные места, а также число мест, в которые можно попасть изо
всех остальных мест.
Класс: TeamBuilder
Метод: vector<int>
specialLocations(vector<string> paths)
Ограничения:
paths содержит от 2 до 50 строк, содержащих n символов ‘0’ и ‘1’, paths[i][i] =
0.
Вход. Массив paths, представляющий собой матрицу, описывающую игровое поле.
Выход. Вектор, содержащий два целых числа: количество мест, из
которых существуют пути во все остальные места, и число мест, в которые можно
попасть изо всех остальных мест.
Пример входа
paths |
{"010","000","110"} |
{"0010","1000","1100","1000"} |
{"01000","00100","00010","00001","10000"} |
Пример выхода
{1,1}
{1,3}
{5,5}
РЕШЕНИЕ
транзитивное замыкание
Построим транзитивное замыкание
матрицы смежности paths. Из вершины i
можно попасть во все остальные вершины тогда и только тогда, когда i - ая строка матрица транзитивного
замыкания содержит только единицы. В вершину j можно попасть изо всех остальных вершин тогда и только тогда,
когда j - ый столбец матрицы
транзитивного замыкания содержит только единицы. В задаче следует подсчитать
количество таких строк и столбцов.
Количество единиц в строке будем
подсчитывать при помощи функции count.
ПРОГРАММА
#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class TeamBuilder
{
public:
vector<int>
specialLocations(vector<string> paths)
{
int k, i, j, n = paths.size();
vector<int> res(2,0);
for (k = 0; k < n; k++) paths[k][k] =
'1';
for (k = 0; k < n; k++)
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (paths[i][k] == '1' && paths[k][j] == '1') paths[i][j] = '1';
for (k = 0; k < n; k++)
{
if (n ==
count(paths[k].begin(),paths[k].end(),'1'))
res[0]++;
for (j = i = 0; i < n; i++) if (paths[i][k] == '1')
j++;
if (j == n) res[1]++;
}
return res;
}
};